home *** CD-ROM | disk | FTP | other *** search
- /*
- ### standard simple driver for integration ###
-
- -----------------------------------------------------------------------------
- NOte: Assume that choose_algorithm will handle nonsymp models
- or models with odd dimensionality
- -Integration is done in standard coods, that is, the coordinate system defining
- the original vector field.
- - Plotting is done in window coordinates, the coord system as defined in
- window_size panel
- - Section is computed by section variables, the coordinates defined in section
- panel
- -----------------------------------------------------------------------------
- - int_driver: 0 no sense of absolute time, integration from i=0 to i_max
- 1 knows absolute time, integration from int_start to int_end
- in int_nsteps;
- 2 knows absolute time, integration from int_start to int_end
- with variable steps but error tolerance less than int_eps
- -----------------------------------------------------------------------------
- THIS DRIVER DEALS ONLY WITH CASE 0 & 1
- -----------------------------------------------------------------------------
- */
- #define TINY 1.e-10
-
- int ode_forward()
- {
- int i,j,iter,i2,dim2,choice,max_iter;
- double fabs(),sin(),fmod(),new_time,new_time_step;
- double *vx,*vx1,*vx2,*vx3,*var_sec,*var_sec_old,*vfull,*delx,*dvector();
- void free_dvector();
- extern int stop,nok,nbad,linear_interpolation;
- extern int model,var_dim,full_dim,int_algorithm,nofrill,i_max,n_poincare,draw_all,polar_coord;
- extern int polar_section,section_index,linear_interpolation, section_count;
- extern int int_driver,int_nstep;
- extern double int_start,int_end;
- extern double cutoff,time,time_step,section_constant,average_return_time;
- extern double *win_var_i,*win_var_f,*param;
- extern int (*f_p)();
- extern char string[];
-
-
- stop = 0;
- /* memory allocation */
- dim2 = var_dim/2;
- vx = dvector(0,var_dim-1);
- vx1 = dvector(0,var_dim-1);
- vx2 = dvector(0,var_dim-1);
- vx3 = dvector(0,var_dim-1);
- var_sec = dvector(0,full_dim-1);
- var_sec_old = dvector(0,full_dim-1);
- vfull = dvector(0,full_dim-1);
- delx = dvector(0,var_dim/2);
-
- /* from window variables to primary variables */
- from_window_variables(vx,win_var_i,polar_coord);
- /* plot and initialize full window variables */
- to_full_variables(vfull,vx,polar_coord);
- if(draw_all){
- (void) draw_record_orbit(vfull,0,0);
- }
-
- /* initialize section variables and full variables including function variables */
- if(!draw_all){
- to_full_variables(var_sec,vx,polar_section);
- for(i=0;i<full_dim;i++) var_sec_old[i] = var_sec[i];
- }
-
- /* choose an appropriate algorithm */
- choice = (int) choose_algorithm();
-
- /* get maximum number of iteration depending on the driver */
- if(int_driver == 0)
- max_iter = i_max;
- else if(int_driver == 1) {
- max_iter = int_nstep;
- time = int_start;
- time_step = (int_end - int_start) / int_nstep;
- }
-
-
- /* initialization of step for implicit symp algorithm */
- /*
- if(choice == 2) {
- (int) f_p(vx1,1,vx,param,time,var_dim);
- for(i=0; i<dim2; i++) delx[i] = time_step * vx1[2*i] + TINY;
- }
- */
-
-
- /* main loop */
- section_count = 0;
- for (iter=1;iter<=max_iter && section_count < n_poincare;iter++){
- /* to ensure the exactness of the ending time */
- if(iter == max_iter -1){
- if(int_driver == 1)
- time = int_end;
- }
- /* break if an orbit diverges */
- for(i=0;i<var_dim;i++){
- if(vx[i] > cutoff || vx[i] < -cutoff) {
- system_mess_proc(1,"Orbits appear to diverge off to an infinity! Stop!");
- goto done;
- }
- }
- /* Not necessary since we are not using a newton's method
- for iteration
- if(choice==4){
- for(i=0; i<dim2; i++){
- i2=i*2;
- vx1[i2] = vx[i2] + 0.9*delx[i];
- vx1[i2+1]=vx[i2+1];
- vx2[i2] = vx1[i2] + 0.2*delx[i];
- vx2[i2+1]=vx[i2+1];
- }
- }
- */
-
- int_onestep(vx1,vx2,vx,&time,time_step,var_dim,choice);
-
- /* from standard to window variables for plotting */
-
- /* Case: draw all orbits */
- if(draw_all){
- /* from window variables to full variables (full dimension)
- include function variables if necessary */
- to_full_variables(vfull,vx1,polar_coord);
- /* test, plot and record an orbit */
- (void) draw_record_orbit(vfull,iter,1);
- }
- /* Case: Draw Poincare sections */
- else {
- /* from window (or standard) to section variables
- including function variables */
- to_full_variables(var_sec,vx1,polar_section);
-
- /* Test for intersections with the Poincare surface plane
- Surface is defined in terms of section variables
- +function variables) */
- if((var_sec_old[section_index] -section_constant) * (var_sec[section_index] - section_constant) <= 0 &&
- (int) (var_sec[section_index]-section_constant) == 0 ){
- if(linear_interpolation==1) {
- /* compute the time step from an old point
- to be on the section surface by linear
- interpolation */
- new_time_step = time_step * (section_constant - var_sec_old[section_index])/(var_sec[section_index]-var_sec_old[section_index]);
- for(i=0; i<var_dim; i++) vx2[i] = vx[i] + new_time_step / time_step * ( vx1[i] - vx[i]);
- }
- else if(linear_interpolation==2){
- new_time = time;
- new_time_step = time_step * (section_constant - var_sec_old[section_index])/(var_sec[section_index]-var_sec_old[section_index]);
- int_onestep(vx2,vx3,vx,&new_time,new_time_step,var_dim,choice);
- }
- else {
- /*
- system_mess_proc(1,"Error: Only linear interpolation available!");
- */
-
- /* Only when Newton's method is used */
- new_time_step = time_step * (section_constant - var_sec_old[section_index])/(var_sec[section_index]-var_sec_old[section_index]);
- nl_interpol(&new_time_step,vx2,var_sec_old,var_sec,vx,time,time_step,var_dim);
- }
- section_count++;
-
- /* from window variables to full window variables including function variables */
- to_full_variables(vfull,vx2,polar_coord);
- /* Test, draw, and record section */
- (void) draw_record_orbit(vfull,iter,1);
- }
- }
- /* Reset new variables to old */
- for(i=0; i<full_dim; i++) var_sec_old[i] = var_sec[i];
- /* implicit symp algorithm ONLY */
- if(choice == 4){
- for(i=0; i<dim2; i++){
- i2=i*2;
- delx[i] = vx1[i2] - vx[i2];
- vx[i2] = vx1[i2];
- vx[i2+1] = vx1[i2+1];
- }
- }
- else {
- for(i=0; i<var_dim; i++) vx[i] = vx1[i];
- }
- /* break if error is detected or an interrupt is received */
- if(stop) {
- goto done;
- }
- }
-
- done:
- /* reset the final value of window variables */
- to_window_variables(win_var_f,vx,polar_coord);
-
- if((int_driver==0 || int_driver==1) && int_algorithm==4){
- sprintf(string,"Centered Euler: nok=%d nbad=%d\n",nok,nbad);
- system_mess_proc(0,string);
- }
- else if(int_algorithm!=4 && linear_interpolation==0){
- sprintf(string,"New Interpol: nok=%d nbad=%d\n",nok,nbad);
- system_mess_proc(0,string);
- }
-
- free_dvector(vx,0,var_dim-1);
- free_dvector(vx1,0,var_dim-1);
- free_dvector(vx2,0,var_dim-1);
- free_dvector(vx3,0,var_dim-1);
- free_dvector(var_sec,0,full_dim-1);
- free_dvector(var_sec_old,0,full_dim-1);
- free_dvector(vfull,0,full_dim-1);
- free_dvector(delx,0,var_dim/2);
- return(iter);
- }
-